import { ELType, GroupType } from "./ELType";

export default class ELNode {
    id: string;
    type: ELType;
    groupType: GroupType;
    aliasId: string;
    name: string;
    data: string;
    tag: string;
    nodeId: string;
    child: ELNode[];
    comingEdgeText: string; //指向该节点边的标签
    elString: string | undefined;

    properties: Record<string, unknown> | undefined

    //group专用
    startNode: ELNode;
    breakNode: ELNode;
    exceptionNode: ELNode;
    startNum: number;

    //固定值
    maxLineNum: number

    constructor(id: string = "") {
        if (id) this.id = id
        this.child = []
        this.maxLineNum = 25
    }

    public addChild(elNode: ELNode) {
        if (!this.child) this.child = []
        this.child.push(elNode);
    }

    private assert(condition: boolean, msg: string = "") {
        if (!condition) throw new Error(msg);
    }

    //获取节点对应的EL表达式
    //在raw的基础上添加tag和data数据
    public getElString() {
        const tagStr = this.properties?.tag ? `.tag('${this.properties?.tag}')` : ''
        const dataStr = this.properties?.data ? `.data('${this.properties?.data}')` : ''

        return `${this.getElStringRaw()}${tagStr}${dataStr}`
    }

    //获取节点对应的EL表达式
    public getElStringRaw() {
        if (this.type === ELType.ID) return this.nodeId;
        if (this.elString) return this.elString;

        const type = this.type;

        switch (type) {
            case ELType.IF:
                return this.getELString_IF()
            case ELType.GROUP:
                return this.getELString_Group()
            case ELType.SWITCH:
                return this.getELString_SWITCH()
            case ELType.WHEN:
            case ELType.THEN:
                return this.getElString_WHEN_THEN()
        }
    }


    // 给每一行插入空格，用于数据的格式化
    private insertSpace(s: string): string {
        const res = s.split("\n").join("\n    ")
        return `    ${res}`
    }


    //各种节点获取ELstring方法
    //THEN和WHEN放到一起
    private getElString_WHEN_THEN() {
        const children = this.child || [];
        // 这里的id只能是switch链中的
        let idStr = ''
        if (this.aliasId) {
            idStr = this.aliasId.startsWith('tag:') 
            ? `.tag("${this.aliasId.substring(4)}")`
            : `.id("${this.aliasId}")`
        }
        //加上空格回车进行格式化
        debugger
        const childrenELStrings = children.map(item => item.getElString())
        const joins = childrenELStrings.join(",");

        //只有一个节点，不需要THEN或者WHEN标识，直接返回
        if (children.length === 1) {
            if (!idStr || children[0].type === ELType.THEN || children[0].type === ELType.WHEN) {
                //这些情况可以直接解包，去掉多余的THEN和WHEN
                return `${joins}${idStr}`;
            }
        }

        //长度比较小，不需要进行格式化，直接单行输出
        if (joins.length < this.maxLineNum - 6) return `${this.type}(${joins})${idStr}`

        const fomatterJoins = this.insertSpace(childrenELStrings.join(",\n"))
        return `${this.type}(\n${fomatterJoins}\n)${idStr}`
    }

    //对分组节点进行解析
    private getELString_Group() {
        const children = this.child || [];
        //加上空格回车进行格式化
        const childrenELStrings = children.map(item => item.getElString())
        const joins = childrenELStrings.join(",");

        // 配置节点解析
        if (this.groupType === GroupType.CONFIG) {
            const ignoreStr = this.properties?.ignoreError ? `.ignoreError(true)` : ``;
            const anyStr = this.properties?.any ? `any(true)` : ``;
            const mustStr = this.properties?.must ? `must(${this.properties?.must})` : ``;

            return `${joins}${ignoreStr}${anyStr}${mustStr}`
        }

        //与或非表达式解析
        if (this.groupType === GroupType.LOGIC) {
            return this.elString;
        }
        const name = this.groupType;
        // 捕获异常表达式解析
        if (this.groupType === GroupType.CATCH) {
            const exceptionStr = this.exceptionNode.getElString();
            return `${name}(${joins}).DO(${exceptionStr})`
        }
        // 循环节点解析
        const breakStr = !!this.breakNode ? `.BREAK(${this.breakNode.getElString()})` : ""
        const startStr = (this.startNode?.nodeId) ? this.startNode.getElString() : this.startNum;
        if (children.length === 1) return `${name}(${startStr}).DO(${joins})${breakStr}`;
        else return `${name}(${startStr}).DO(WHEN(${joins}))${breakStr}`;
    }

    private getELString_IF() {
        const children = this.child || [];
        //加上空格回车进行格式化
        const childrenELStrings = children.map(item => item.getElString())
        const joins = childrenELStrings.join(",");

        //长度比较小，不需要进行格式化，直接单行输出
        if (joins.length < this.maxLineNum - 4) return `IF(${joins})`

        const fomatterJoins = this.insertSpace(childrenELStrings.join(",\n"))
        return `IF(\n${fomatterJoins}\n)`;
    }

    private getELString_SWITCH() {
        const children = this.child || [];
        //加上空格回车进行格式化
        const childrenELStrings = children.map(item => item.getElString())
        const joins = childrenELStrings.join(",");

        if (joins.length < this.maxLineNum - 13 - this.nodeId.length)
            return `SWITCH(${this.nodeId}).to(${joins})`;

        const fomatterJoins = this.insertSpace(childrenELStrings.join(",\n"))
        return `SWITCH(${this.nodeId}).to(\n${fomatterJoins}\n)`;
    }
}